表单处理

在现代Web应用中,表单是用户与应用交互的重要方式之一。React 提供了强大的工具来处理表单,使得开发者可以轻松地管理表单的状态和验证。本教程将详细介绍如何在 React 中处理表单,包括受控组件、非受控组件、表单验证以及一些常用的表单库。

1. 受控组件 vs 非受控组件

在 React 中,表单元素可以是受控组件或非受控组件。理解这两者的区别是掌握表单处理的基础。

1.1 受控组件

受控组件是指其值由 React 的 state 管理的表单元素。这意味着表单元素的值完全由 React 控制,每当用户输入时,React 会更新 state,从而更新表单元素的值。

import React, { useState } from 'react';

function ControlledForm() {
  const [name, setName] = useState('');

  const handleChange = (event) => {
    setName(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    alert(`Submitted name: ${name}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" value={name} onChange={handleChange} />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

export default ControlledForm;

1.2 非受控组件

非受控组件是指其值不由 React 管理的表单元素。相反,表单元素的值由 DOM 本身管理。通常使用 ref 来访问表单元素的值。

import React, { useRef } from 'react';

function UncontrolledForm() {
  const inputRef = useRef(null);

  const handleSubmit = (event) => {
    event.preventDefault();
    alert(`Submitted name: ${inputRef.current.value}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" ref={inputRef} />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

export default UncontrolledForm;

2. 表单验证

表单验证是确保用户输入数据符合预期的重要步骤。React 本身不提供内置的表单验证功能,但可以通过组合 state 和条件渲染来实现简单的验证。

2.1 简单的表单验证

import React, { useState } from 'react';

function ValidationForm() {
  const [name, setName] = useState('');
  const [error, setError] = useState('');

  const handleChange = (event) => {
    setName(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    if (name.trim() === '') {
      setError('Name is required');
    } else {
      setError('');
      alert(`Submitted name: ${name}`);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" value={name} onChange={handleChange} />
      </label>
      {error && <p style={{ color: 'red' }}>{error}</p>}
      <button type="submit">Submit</button>
    </form>
  );
}

export default ValidationForm;

2.2 使用第三方库

对于更复杂的表单验证,可以使用第三方库,如 Formik 或 React Hook Form。这些库提供了更强大的验证功能和更好的开发体验。

2.2.1 Formik 示例

import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';

const validationSchema = Yup.object().shape({
  name: Yup.string().required('Name is required'),
  email: Yup.string().email('Invalid email').required('Email is required'),
});

function FormikForm() {
  return (
    <Formik
      initialValues={{ name: '', email: '' }}
      validationSchema={validationSchema}
      onSubmit={(values) => {
        alert(JSON.stringify(values, null, 2));
      }}
    >
      <Form>
        <label>
          Name:
          <Field type="text" name="name" />
          <ErrorMessage name="name" component="div" style={{ color: 'red' }} />
        </label>
        <label>
          Email:
          <Field type="email" name="email" />
          <ErrorMessage name="email" component="div" style={{ color: 'red' }} />
        </label>
        <button type="submit">Submit</button>
      </Form>
    </Formik>
  );
}

export default FormikForm;

2.2.2 React Hook Form 示例

import React from 'react';
import { useForm } from 'react-hook-form';

function HookForm() {
  const { register, handleSubmit, formState: { errors } } = useForm();

  const onSubmit = (data) => {
    alert(JSON.stringify(data, null, 2));
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>
        Name:
        <input {...register("name", { required: true })} />
        {errors.name && <span style={{ color: 'red' }}>This field is required</span>}
      </label>
      <label>
        Email:
        <input {...register("email", { required: true, pattern: /^\S+@\S+$/i })} />
        {errors.email && <span style={{ color: 'red' }}>Invalid email</span>}
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

export default HookForm;

3. 实践练习

3.1 练习:创建一个简单的注册表单

要求:

  • 包含用户名、邮箱和密码字段。
  • 使用 Formik 或 React Hook Form 进行表单验证。
  • 提交表单时显示用户输入的数据。

3.2 练习:创建一个多步骤表单

要求:

  • 表单分为多个步骤(例如:个人信息、地址信息、支付信息)。
  • 使用 state 管理当前步骤。
  • 每个步骤的表单元素应进行验证。
  • 提交表单时显示所有步骤的数据。

4. 总结

表单处理是 React 开发中的重要部分。通过理解受控组件和非受控组件的区别,以及如何使用表单验证,你可以构建出功能强大且用户友好的表单。结合第三方库如 Formik 和 React Hook Form,可以进一步提升表单处理的效率和可维护性。

希望本教程能帮助你更好地掌握 React 中的表单处理技巧。继续实践和探索,你将能够构建出更加复杂和高效的表单应用。